package com.common.utils;

import org.apache.commons.lang.StringUtils;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author baixiaoshen
 */
public class StringUtil {

    /**
     * 过滤HTMl标签
     *
     * @param htmlStr
     * @return
     */
    public static String removeHTMLTag(String htmlStr) {
        String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式
        Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
        Matcher m_html = p_html.matcher(htmlStr);
        htmlStr = m_html.replaceAll(""); // 过滤html标签
        return htmlStr.trim(); // 返回文本字符串
    }

    public static String subString(String content, String s, String s1) {
        if (content.indexOf(s) != -1)
            content = content.substring(content.indexOf(s), content.length());
        if (content.indexOf(s1) != -1)
            content = content.substring(0, content.indexOf(s1));
        return content;
    }

    /**
     * 解码json字符串
     *
     * @param jsonStr
     * @return
     */
    public static String descodeJsonString(String jsonStr) {
        if (jsonStr == null || jsonStr.isEmpty())
            return "";
        try {
            jsonStr = jsonStr.replaceAll("\\\\/", "/");
            jsonStr = jsonStr.replaceAll("\\\\t", "\t");
            jsonStr = jsonStr.replaceAll("\\\\r", "\r");
            jsonStr = jsonStr.replaceAll("\\\\n", "\n");
            jsonStr = jsonStr.replaceAll("\\\\f", "\f");
            jsonStr = jsonStr.replaceAll("\\\\b", "\b");
            jsonStr = jsonStr.replaceAll("\\\\\"", "\"");
            // jsonStr = jsonStr.replaceAll("\\\\\\\\", "\\");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return jsonStr;
    }

    /**
     * 统计一个字符串出现的次数
     *
     * @param source
     * @param regexNew
     * @return
     */
    public static int finder(String source, String regexNew) {
        String regex = "[a-zA-Z]+";
        if (regexNew != null && !regexNew.equals("")) {
            regex = regexNew;
        }
        Pattern expression = Pattern.compile(regex);
        Matcher matcher = expression.matcher(source);
        int n = 0;
        while (matcher.find()) {
            n++;
        }
        return n;
    }

    /**
     * 截取字符串
     *
     * @param s
     * @param maxLength
     * @return
     */
    public static String interceptStr(String s, int maxLength) {
        if (isBlank(s)) {
            return "";
        }
        return s.length() > maxLength ? s.substring(0, maxLength - 1) + "..." : s;
    }

    /**
     * @param s
     * @return
     */
    public static String conNum(String s) {
        return s.replaceAll("一", "1").replaceAll("二", "2").replaceAll("三", "3")
                .replaceAll("四", "4").replaceAll("五", "5").replaceAll("六", "6")
                .replaceAll("七", "7").replaceAll("八", "8").replaceAll("九", "9")
                .replaceAll("零", "0").replaceAll("两", "2");
    }

    /**
     * 人民币转大写
     *
     * @param value
     * @return
     */
    public static String hangeToBig(double value) {
        char[] hunit = {'拾', '佰', '仟'}; // 段内位置表示
        char[] vunit = {'万', '亿'}; // 段名表示
        char[] digit = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'}; // 数字表示
        long midVal = (long) (value * 100); // 转化成整形
        String valStr = String.valueOf(midVal); // 转化成字符串

        String head = valStr.substring(0, valStr.length() - 2); // 取整数部分
        String rail = valStr.substring(valStr.length() - 2); // 取小数部分

        String prefix = ""; // 整数部分转化的结果
        String suffix = ""; // 小数部分转化的结果
        // 处理小数点后面的数
        if (rail.equals("00")) { // 如果小数部分为0
            suffix = "整";
        } else {
            suffix = digit[rail.charAt(0) - '0'] + "角" + digit[rail.charAt(1) - '0'] + "分"; // 否则把角分转化出来
        }
        // 处理小数点前面的数
        char[] chDig = head.toCharArray(); // 把整数部分转化成字符数组
        char zero = '0'; // 标志'0'表示出现过0
        byte zeroSerNum = 0; // 连续出现0的次数
        for (int i = 0; i < chDig.length; i++) { // 循环处理每个数字
            int idx = (chDig.length - i - 1) % 4; // 取段内位置
            int vidx = (chDig.length - i - 1) / 4; // 取段位置
            if (chDig[i] == '0') { // 如果当前字符是0
                zeroSerNum++; // 连续0次数递增
                if (zero == '0') { // 标志
                    zero = digit[0];
                } else if (idx == 0 && vidx > 0 && zeroSerNum < 4) {
                    prefix += vunit[vidx - 1];
                    zero = '0';
                }
                continue;
            }
            zeroSerNum = 0; // 连续0次数清零
            if (zero != '0') { // 如果标志不为0,则加上,例如万,亿什么的
                prefix += zero;
                zero = '0';
            }
            prefix += digit[chDig[i] - '0']; // 转化该数字表示
            if (idx > 0) {
                prefix += hunit[idx - 1];
            }
            if (idx == 0 && vidx > 0) {
                prefix += vunit[vidx - 1]; // 段结束位置应该加上段名如万,亿
            }
        }

        if (prefix.length() > 0)
            prefix += '圆'; // 如果整数部分存在,则有圆的字样
        return prefix + suffix; // 返回正确表示

    }

    /**
     * 判断字符串是否为空
     *
     * @param s
     * @return
     */
    public static boolean isBlank(String s) {
        if (s == null || s.length() == 0) {
            return true;
        }
        return false;
    }

    /**
     * 首字母小写
     *
     * @param s String
     * @return String
     */
    public static String firstCharLowerCase(String s) {
        if (s == null || "".equals(s)) {
            return ("");
        }
        return s.substring(0, 1).toLowerCase() + s.substring(1);
    }

    /**
     * 首字母大写
     *
     * @param s String
     * @return String
     */
    public static String firstCharUpperCase(String s) {
        if (s == null || "".equals(s)) {
            return ("");
        }
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    /**
     * aBbbCcc => a_bbb_ccc
     *
     * @param property
     * @return String
     */
    public static String getConverColName(String property) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < property.length(); i++) { // 遍历property如果有大写字母则将大写字母转换为_加小写
            char cur = property.charAt(i);
            if (Character.isUpperCase(cur)) {
                sb.append("_");
                sb.append(Character.toLowerCase(cur));
            } else {
                sb.append(cur);
            }
        }
        return sb.toString();
    }

    /**
     * a_bbb_ccc => aBbbCcc
     *
     * @param property
     * @return String
     */
    public static String getConverColBean(String property) {
        if (isBlank(property) || property.indexOf("_") == -1) {
            return property;
        }
        StringBuffer sb = new StringBuffer();
        boolean flag = false;
        for (int i = 0; i < property.length(); i++) { // 遍历property如果有大写字母则将大写字母转换为_加小写
            char cur = property.charAt(i);
            if ('_' == cur) {
                flag = true;
                continue;
            } else {
                sb.append(flag ? Character.toUpperCase(cur) : cur);
                flag = false;
            }
        }
        return sb.toString();
    }

    /**
     * 是否有中文字符
     *
     * @param s
     * @return
     */
    public static boolean hasCn(String s) {
        if (s == null) {
            return false;
        }
        return countCn(s) > s.length();
    }

    /**
     * 获得字符。符合中文习惯。
     *
     * @param s
     * @param len
     * @return
     */
    public static String getCn(String s, int len) {
        if (s == null) {
            return s;
        }
        int sl = s.length();
        if (sl <= len) {
            return s;
        }
        // 留出一个位置用于…
        len -= 1;
        int maxCount = len * 2;
        int count = 0;
        int i = 0;
        while (count < maxCount && i < sl) {
            if (s.codePointAt(i) < 256) {
                count++;
            } else {
                count += 2;
            }
            i++;
        }
        if (count > maxCount) {
            i--;
        }
        return s.substring(0, i) + "…";
    }

    /**
     * 计算GBK编码的字符串的字节数
     *
     * @param s
     * @return
     */
    public static int countCn(String s) {
        if (s == null) {
            return 0;
        }
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.codePointAt(i) < 256) {
                count++;
            } else {
                count += 2;
            }
        }
        return count;
    }

    /**
     * 文本转html
     *
     * @param txt
     * @return
     */
    public static String txt2htm(String txt) {
        if (isBlank(txt)) {
            return txt;
        }
        StringBuilder bld = new StringBuilder();
        char c;
        for (int i = 0; i < txt.length(); i++) {
            c = txt.charAt(i);
            switch (c) {
                case '&':
                    bld.append("&amp;");
                    break;
                case '<':
                    bld.append("&lt;");
                    break;
                case '>':
                    bld.append("&gt;");
                    break;
                case '"':
                    bld.append("&quot;");
                    break;
                case ' ':
                    bld.append("&nbsp;");
                    break;
                case '\n':
                    bld.append("<br/>");
                    break;
                default:
                    bld.append(c);
                    break;
            }
        }
        return bld.toString();
    }

    /**
     * html转文本
     *
     * @param htm
     * @return
     */
    public static String htm2txt(String htm) {
        if (htm == null) {
            return htm;
        }
        htm = htm.replace("&amp;", "&");
        htm = htm.replace("&lt;", "<");
        htm = htm.replace("&gt;", ">");
        htm = htm.replace("&quot;", "\"");
        htm = htm.replace("&nbsp;", " ");
        htm = htm.replace("<br/>", "\n");
        return htm;
    }

    /**
     * 全角-->半角
     *
     * @param qjStr
     * @return
     */
    public String Q2B(String qjStr) {
        String outStr = "";
        String Tstr = "";
        byte[] b = null;
        for (int i = 0; i < qjStr.length(); i++) {
            try {
                Tstr = qjStr.substring(i, i + 1);
                b = Tstr.getBytes("unicode");
            } catch (java.io.UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (b[3] == -1) {
                b[2] = (byte) (b[2] + 32);
                b[3] = 0;
                try {
                    outStr = outStr + new String(b, "unicode");
                } catch (java.io.UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            } else
                outStr = outStr + Tstr;
        }
        return outStr;
    }

    public static final char[] N62_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
            'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
            's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
            'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
    public static final char[] N36_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
            'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
            's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

    private static StringBuilder longToNBuf(long l, char[] chars) {
        int upgrade = chars.length;
        StringBuilder result = new StringBuilder();
        int last;
        while (l > 0) {
            last = (int) (l % upgrade);
            result.append(chars[last]);
            l /= upgrade;
        }
        return result;
    }

    /**
     * 长整数转换成N62
     *
     * @param l
     * @return
     */
    public static String longToN62(long l) {
        return longToNBuf(l, N62_CHARS).reverse().toString();
    }

    public static String longToN36(long l) {
        return longToNBuf(l, N36_CHARS).reverse().toString();
    }

    /**
     * 长整数转换成N62
     *
     * @param l
     * @param length 如N62不足length长度，则补足0。
     * @return
     */
    public static String longToN62(long l, int length) {
        StringBuilder sb = longToNBuf(l, N62_CHARS);
        for (int i = sb.length(); i < length; i++) {
            sb.append('0');
        }
        return sb.reverse().toString();
    }

    public static String longToN36(long l, int length) {
        StringBuilder sb = longToNBuf(l, N36_CHARS);
        for (int i = sb.length(); i < length; i++) {
            sb.append('0');
        }
        return sb.reverse().toString();
    }

    /**
     * N62转换成整数
     *
     * @param n62
     * @return
     */
    public static long n62ToLong(String n62) {
        return nToLong(n62, N62_CHARS);
    }

    public static long n36ToLong(String n36) {
        return nToLong(n36, N36_CHARS);
    }

    private static long nToLong(String s, char[] chars) {
        char[] nc = s.toCharArray();
        long result = 0;
        long pow = 1;
        for (int i = nc.length - 1; i >= 0; i--, pow *= chars.length) {
            int n = findNIndex(nc[i], chars);
            result += n * pow;
        }
        return result;
    }

    private static int findNIndex(char c, char[] chars) {
        for (int i = 0; i < chars.length; i++) {
            if (c == chars[i]) {
                return i;
            }
        }
        throw new RuntimeException("N62(N36)非法字符：" + c);
    }

    /**
     * 方法描述:把数组1,2,3转化成字符串
     *
     * @param integerList
     * @return
     */
    public static String getSplitStringByInt(List<Integer> integerList) {
        if (null != integerList && integerList.size() != 0) {
            String splitString = "";
            for (int intInstance : integerList) {
                splitString += intInstance + ",";
            }
            return splitString.substring(0, splitString.length() - 1);
        } else {
            return null;
        }
    }

    /**
     * 方法描述:把数组1,2,3转化成字符串
     *
     * @param stringList
     * @return
     */
    public static String getSplitStringByString(List<String> stringList) {
        if (null != stringList && stringList.size() != 0) {
            String splitString = "";
            for (String stringInstance : stringList) {
                splitString += stringInstance + ",";
            }
            return splitString.substring(0, splitString.length() - 1);
        } else {
            return null;
        }
    }

    /**
     * 16进制转字符
     *
     * @param val
     * @return
     */
    public static char hexToChar(String val) {
        int intVal = Integer.parseInt(val, 16);
        return (char) intVal;
    }

    /**
     * 16进制转字符串
     *
     * @param vals
     * @return
     */
    public static String hexToStr(String[] vals) {
        StringBuilder sbBuilder = new StringBuilder();
        for (String val : vals) {
            if (val.equals(""))
                continue;
            sbBuilder.append(hexToChar(val));
        }
        return sbBuilder.toString();
    }

    // private static final Pattern regexDecodeText =
    // Pattern.compile("=\\?(.[^\\?]+)\\?(.)\\?(.[^\\?]+)\\?=");
    /**
     * 解码字符串
     *
     * @param s
     * @return
     * @throws IOException
     */
    /*
     * public static String decodeText(String s) { if ((s == null) ||
	 * (s.length() == 0)) { return s; } try { return MimeUtility.decodeText(s);
	 * } catch (UnsupportedEncodingException e) { return s; }
	 * 
	 * Matcher matcher = regexDecodeText.matcher(s); if (!matcher.find()) return
	 * s; String strEncoding = matcher.group(1); String strType =
	 * matcher.group(2); String strEncodeStr = matcher.group(3); if
	 * ((!"B".equalsIgnoreCase(strType)) && (!"Q".equalsIgnoreCase(strType)))
	 * return s; FilterInputStream fileInputStream = null; ByteArrayInputStream
	 * byteArrayInputStream = null; try { byteArrayInputStream = new
	 * ByteArrayInputStream(strEncodeStr.getBytes()); if
	 * ("B".equalsIgnoreCase(strType)) { fileInputStream = new
	 * BASE64DecoderStream(byteArrayInputStream); } else { fileInputStream = new
	 * QDecoderStream(byteArrayInputStream); } int iDataLen =
	 * fileInputStream.available(); byte[] bytes = new byte[iDataLen];
	 * 
	 * @SuppressWarnings("unused") int iReadLen = fileInputStream.read(bytes, 0,
	 * iDataLen); String strReturn = new String(bytes, strEncoding); return
	 * strReturn; } catch (Exception ex) { return s; } finally { if
	 * (fileInputStream != null) { fileInputStream.close(); fileInputStream =
	 * null; } if (byteArrayInputStream != null) { byteArrayInputStream.close();
	 * byteArrayInputStream = null; } }
	 * 
	 * }
	 */

    /**
     * 将参数以模版形式组装成字符串
     */
    public static String formatToTemplate(String msg, String... strings) {
        if (StringUtils.isBlank(msg)) {
            return StringUtils.EMPTY;
        }
        String[] strs = StringUtils.split(msg, "{P}");
        StringBuffer sb = new StringBuffer(strs[0]);
        try {
            for (int i = 0; i < strings.length; i++) {
                sb.append(strings[i]);
                sb.append(strs[i + 1]);
            }
        } catch (Exception e) {
            // do nothing;
        }
        return sb.toString();
    }

    /**
     * 用maskStr替换target字符，若传入的last为正数，则保留last位数字符不被替换，反之，则保留最后last位数的字符不被替换
     *
     * @param target
     * @param maskStr
     * @return
     */
    public static String maskMidString(String target, String maskStr, int front, int last) {
        if (target == null)
            return null;
        int length = target.length() - Math.abs(front) - Math.abs(last);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append(maskStr);
        }
        sb.insert(0, StringUtils.substring(target, 0, front));
        if (length > 0) {
            sb.append(StringUtils.substring(target, target.length() - Math.abs(last),
                    target.length()));
        }
        return sb.toString();
    }

    /**
     * 用maskStr替换target字符，若传入的last为正数，则保留last位数字符不被替换，反之，则保留最后last位数的字符不被替换
     *
     * @param target
     * @param maskStr
     * @return
     */
    public static String maskString(String target, String maskStr, int last) {
        if (target == null)
            return null;
        int length = target.length() - Math.abs(last);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append(maskStr);
        }
        if (last > 0) {
            sb.insert(0, StringUtils.substring(target, 0, last));
        } else {
            sb.append(StringUtils.substring(target, last));
        }
        return sb.toString();
    }

    /**
     * 用maskStr替换target字符，传入的front为保留的前几位，last为保留的最后几位，front和last应该大于0，否则取其绝对值
     *
     * @param target
     * @param maskStr
     * @param front
     * @param last
     * @return
     */
    public static String maskString(String target, String maskStr, int front, int last) {
        if (target == null)
            return null;
        int length = target.length() - Math.abs(front) - Math.abs(last);
        int flength = target.length() - Math.abs(front);
        int nlength = length > 0 ? length : flength;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < nlength; i++) {
            sb.append(maskStr);
        }
        sb.insert(0, StringUtils.substring(target, 0, front));
        if (length > 0) {
            sb.append(StringUtils.substring(target, target.length() - Math.abs(last),
                    target.length()));
        }
        return sb.toString();
    }

    /**
     * 带空格的mask
     *
     * @param target
     * @param maskStr
     * @param blankPerChar
     * @param last
     * @return
     */
    public static String maskStrWithBlank(String target, String maskStr, int blankPerChar, int last) {
        if (target == null)
            return null;
        String maskResult = maskString(target, maskStr, last);
        char[] chars = maskResult.toCharArray();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            if (i % blankPerChar == 0) {
                sb.append(" ");
            }
            sb.append(chars[i]);
        }
        return sb.toString();
    }

    /**
     * 用maskStr替换target字符，传入的front为保留的前几位，last为保留的最后几位，front和last应该大于0，否则取其绝对值
     *
     * @param target
     * @param maskStr
     * @param front
     * @param last
     * @param count   中间被替换字符的个数
     * @return
     */
    public static String maskString(String target, String maskStr, int front, int last, int count) {
        if (target == null)
            return null;
        int length = target.length() - Math.abs(front) - Math.abs(last);
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < count; i++) {
            sb.append(maskStr);
        }
        sb.insert(0, StringUtils.substring(target, 0, front));
        if (length > 0) {
            sb.append(StringUtils.substring(target, target.length() - Math.abs(last),
                    target.length()));
        }
        return sb.toString();
    }

    /**
     * 删除input字符串中的html格式
     *
     * @param input
     * @param length
     * @return
     */
    public static String splitAndFilterString(String input, int length) {
        if (input == null || input.trim().equals("")) {
            return "";
        }
        // 去掉所有html元素,
        String str = input.replaceAll("\\&[a-zA-Z]{1,10};", "").replaceAll("<[^>]*>", "");
        str = str.replaceAll("[(/>)<]", "");
        int len = str.length();
        if (len <= length) {
            return str;
        } else {
            str = str.substring(0, length);
            str += "......";
        }
        return str;
    }

}
